#include "unity.h"
#include "mock_bsp_test_commom.h" // CMock 生成的 mock 头文件
#include "Rt_LUT_Config.h"


// Test instance
XRt1553B testInstance;

void setUp(void)
{
    // Initialize test instance before each test
    memset(&testInstance, 0, sizeof(testInstance));
    testInstance.BaseAddress = 0x40000000;
}

void tearDown(void)
{
    // Clean up after each test
}

// Test normal operation with even byte count
void test_RxFromSubAddr_NormalEvenBytes(void)
{
    u8 dataBuffer[16];
    u32 subAddr = 1;
    u32 byteLength = 8;
    u32 wordLength = byteLength / 2;
    u32 startPtr = 0x100;
    
    // Configure test instance
    testInstance.rx_SAcfg[subAddr].valid_data_bytes = 16;
    testInstance.rx_SAcfg[subAddr].DataBlock_start_ptr = startPtr;
    testInstance.rx_SAcfg[subAddr].mm_mode = XRT53_MM_SINGLE_MSG;
    
    // Expect memory reads
    for (u32 i = 0; i < wordLength; i++) {
        XRt1553B_ReadMem_ExpectAndReturn(testInstance.BaseAddress, startPtr + i, 0x1234 + i);
    }
    
    // Execute function
    u32 result = XRt1553B_RxFromSubAddr(&testInstance, subAddr, dataBuffer, byteLength);
    
    // Verify result
    TEST_ASSERT_EQUAL_UINT32(byteLength, result);
    
    // Verify data
    u16* ptr = (u16*)dataBuffer;
    for (u32 i = 0; i < wordLength; i++) {
        TEST_ASSERT_EQUAL_UINT16(0x1234 + i, ptr[i]);
    }
}

// Test normal operation with odd byte count
void test_RxFromSubAddr_NormalOddBytes(void)
{
    u8 dataBuffer[16];
    u32 subAddr = 2;
    u32 byteLength = 7; // Odd number of bytes
    u32 wordLength = (byteLength - 1) / 2; // Should read 3 words (6 bytes)
    u32 startPtr = 0x200;
    
    // Configure test instance
    testInstance.rx_SAcfg[subAddr].valid_data_bytes = 16;
    testInstance.rx_SAcfg[subAddr].DataBlock_start_ptr = startPtr;
    testInstance.rx_SAcfg[subAddr].mm_mode = XRT53_MM_SINGLE_MSG;
    
    // Expect memory reads
    for (u32 i = 0; i < wordLength; i++) {
        XRt1553B_ReadMem_ExpectAndReturn(testInstance.BaseAddress, startPtr + i, 0x5678 + i);
    }
    
    // Execute function
    u32 result = XRt1553B_RxFromSubAddr(&testInstance, subAddr, dataBuffer, byteLength);
    
    // Verify result - should return 6 bytes (3 words)
    TEST_ASSERT_EQUAL_UINT32(wordLength * 2, result);
    
    // Verify data
    u16* ptr = (u16*)dataBuffer;
    for (u32 i = 0; i < wordLength; i++) {
        TEST_ASSERT_EQUAL_UINT16(0x5678 + i, ptr[i]);
    }
}

// Test when requested bytes exceed valid bytes
void test_RxFromSubAddr_ExceedValidBytes(void)
{
    u8 dataBuffer[16];
    u32 subAddr = 3;
    u32 byteLength = 20; // Exceeds valid bytes
    
    // Configure test instance
    testInstance.rx_SAcfg[subAddr].valid_data_bytes = 16; // Less than requested
    
    // Execute function
    u32 result = XRt1553B_RxFromSubAddr(&testInstance, subAddr, dataBuffer, byteLength);
    
    // Verify result - should return 0
    TEST_ASSERT_EQUAL_UINT32(0, result);
}

// Test circular buffer mode
void test_RxFromSubAddr_CircularBufferMode(void)
{
    u8 dataBuffer[16];
    u32 subAddr = 4;
    u32 byteLength = 4;
    u32 wordLength = byteLength / 2;
    u32 startPtr = 0x300;
    
    // Configure test instance
    testInstance.rx_SAcfg[subAddr].valid_data_bytes = 16;
    testInstance.rx_SAcfg[subAddr].DataBlock_start_ptr = startPtr;
    testInstance.rx_SAcfg[subAddr].mm_mode = XRT53_MM_CIRCULAR_BUFFER;
    
    // Expect memory reads
    for (u32 i = 0; i < wordLength; i++) {
        XRt1553B_ReadMem_ExpectAndReturn(testInstance.BaseAddress, startPtr + i, 0xABCD + i);
    }
    
    // Expect memory writes for circular buffer pointer updates
    XRt1553B_WriteMem_Expect(testInstance.BaseAddress, XRT53_LUT_A_RX(subAddr), startPtr);
    XRt1553B_WriteMem_Expect(testInstance.BaseAddress, XRT53_LUT_B_RX(subAddr), startPtr);
    
    // Execute function
    u32 result = XRt1553B_RxFromSubAddr(&testInstance, subAddr, dataBuffer, byteLength);
    
    // Verify result
    TEST_ASSERT_EQUAL_UINT32(byteLength, result);
}

// Test zero byte request
void test_RxFromSubAddr_ZeroBytes(void)
{
    u8 dataBuffer[16];
    u32 subAddr = 5;
    u32 byteLength = 0;
    u32 startPtr = 0x400;
    
    // Configure test instance
    testInstance.rx_SAcfg[subAddr].valid_data_bytes = 16;
    testInstance.rx_SAcfg[subAddr].DataBlock_start_ptr = startPtr;
    
    // Execute function
    u32 result = XRt1553B_RxFromSubAddr(&testInstance, subAddr, dataBuffer, byteLength);
    
    // Verify result - should return 0 bytes
    TEST_ASSERT_EQUAL_UINT32(0, result);
}

// Test boundary condition - exactly valid bytes
void test_RxFromSubAddr_ExactValidBytes(void)
{
    u8 dataBuffer[32];
    u32 subAddr = 6;
    u32 byteLength = 16; // Exactly matches valid bytes
    u32 wordLength = byteLength / 2;
    u32 startPtr = 0x500;
    
    // Configure test instance
    testInstance.rx_SAcfg[subAddr].valid_data_bytes = 16;
    testInstance.rx_SAcfg[subAddr].DataBlock_start_ptr = startPtr;
    testInstance.rx_SAcfg[subAddr].mm_mode = XRT53_MM_SINGLE_MSG;
    
    // Expect memory reads
    for (u32 i = 0; i < wordLength; i++) {
        XRt1553B_ReadMem_ExpectAndReturn(testInstance.BaseAddress, startPtr + i, 0xDCBA + i);
    }
    
    // Execute function
    u32 result = XRt1553B_RxFromSubAddr(&testInstance, subAddr, dataBuffer, byteLength);
    
    // Verify result
    TEST_ASSERT_EQUAL_UINT32(byteLength, result);
}

